نحوه استفاده از عملگر ادغام تهی (??) جاوااسکریپت برای تخصیص کارآمد مقدار پیشفرض، از جمله تکنیکهای زنجیرهای پیشرفته برای سناریوهای پیچیده و بهبود خوانایی کد را بیاموزید.
تسلط بر زنجیره عملگر ادغام تهی جاوااسکریپت: تخصیص موثر مقدار پیشفرض
عملگر ادغام تهی (??) جاوااسکریپت ابزاری قدرتمند برای ارائه مقادیر پیشفرض به روشی مختصر و خوانا است. این راهنما عمیقاً به ظرافتهای این عملگر میپردازد، بهویژه با تمرکز بر زنجیرهسازی و نحوه استفاده از آن برای تخصیص موثر مقدار پیشفرض در سناریوهای مختلف. ما مزایا، مثالهای عملی و تکنیکهای پیشرفته را بررسی خواهیم کرد تا به شما در نوشتن کد جاوااسکریپت تمیزتر و قویتر کمک کنیم.
درک عملگر ادغام تهی (??)
عملگر ادغام تهی (??) یک مقدار را ارزیابی میکند و اگر آن مقدار `null` یا `undefined` باشد، یک مقدار پیشفرض را برمیگرداند. این یک جایگزین خاصتر و اغلب ترجیحدادهشده برای عملگر OR (||) است، که برای مجموعه وسیعتری از مقادیر نادرست (به عنوان مثال، `0`، `''`، `false`) به `false` ارزیابی میشود.
نحو پایه ساده است:
const result = value ?? defaultValue;
در اینجا، `value` عبارتی است که باید ارزیابی شود. اگر `value` برابر با `null` یا `undefined` باشد، `defaultValue` برگردانده میشود. در غیر این صورت، خود `value` برگردانده میشود.
چرا از ?? به جای || استفاده کنیم؟
مزیت اصلی `??` نسبت به `||` در دقت آن نهفته است. این مثال ها را در نظر بگیرید:
const count = 0; const result = count || 10; // result will be 10 (because 0 is falsy)const count = 0; const result = count ?? 10; // result will be 0 (because 0 is neither null nor undefined)
در حالت اول، با استفاده از `||`، ما به اشتباه `10` را به `result` اختصاص میدهیم حتی زمانی که `count` به طور مشروع `0` است. عملگر `??` از این امر جلوگیری میکند و تنها در صورتی جایگزین میشود که مقدار اصلی `null` یا `undefined` باشد.
زنجیره کردن عملگر ادغام تهی
زنجیره کردن عملگر ادغام تهی به شما امکان می دهد چندین مقدار را به ترتیب بررسی کنید و فقط در صورتی یک مقدار پیش فرض ارائه دهید که همه مقادیر قبلی `null` یا `undefined` باشند. این برای دسترسی به ویژگی های تودرتو یا مقادیر پیش فرض در ساختارهای داده پیچیده بسیار مفید است.
مثال زنجیره ای پایه
تصور کنید یک شی دارید که نمایانگر نمایه یک کاربر است و می خواهید زبان ترجیحی او را نمایش دهید. زبان ممکن است در چند مکان مختلف تنظیم شود، با یک مقدار پیش فرض در صورتی که هیچ کدام مشخص نشده باشد.
const userProfile = {
preferences: {
language: null, // Or undefined
},
};
const preferredLanguage = userProfile.preferences.language ?? 'en';
console.log(preferredLanguage); // Output: 'en'
اکنون، زنجیره ای را برای بررسی `preferences` احتمالی از دست رفته اضافه کنیم:
const userProfile = {}; // preferences might be missing
const preferredLanguage = userProfile.preferences?.language ?? 'en'; // Uses optional chaining for safety
console.log(preferredLanguage); // Output: 'en'
در این مثال بهبود یافته، اگر `userProfile.preferences` برابر با `undefined` باشد، کد به آرامی به مقدار پیشفرض 'en' میرود. `?.` (عملگر زنجیره اختیاری) از بروز خطا هنگام دسترسی به ویژگیهای اشیاء بالقوه تعریف نشده جلوگیری میکند.
زنجیره ای پیشرفته برای تخصیص چندگانه پیشفرض
زنجیره ای `??` امکان تخصیص چندگانه پیشفرض را در یک عبارت واحد فراهم میکند. ارزیابی از چپ به راست ادامه می یابد و اولین مقدار غیر null/undefined برخورد شده استفاده می شود.
const settings = {
theme: null,
font: undefined,
size: 16,
};
const theme = settings.theme ?? settings.defaultTheme ?? 'light'; // Checks settings.theme, then settings.defaultTheme, then defaults to 'light'
const font = settings.font ?? 'Arial'; // If font is null or undefined, defaults to Arial
const fontSize = settings.fontSize ?? 12; //if fontSize is undefined, default is 12
console.log(theme); // Output: 'light'
console.log(font); // Output: 'Arial'
console.log(fontSize); // Output: 12, because settings.fontSize is undefined and no default is in settings
در مثال `theme`، اگر `settings.theme` برابر با null یا undefined باشد، کد `settings.defaultTheme` را بررسی میکند. اگر *آن* نیز null یا undefined باشد، مقدار پیشفرض 'light' استفاده میشود. این رویکرد تخصیص مقادیر پیشفرض را هنگامی که سطوح مختلفی از بازگشت به عقب مورد نیاز است، بسیار ساده میکند.
دسترسی به ویژگی های تودرتو با زنجیره ای
عملگر ادغام تهی هنگام کار با ساختارهای شی عمیقاً تودرتو میدرخشد، جایی که دسترسی به یک ویژگی ممکن است منجر به مقادیر `undefined` در سطوح مختلف شود.
const user = {
details: {
address: {
city: null,
},
},
};
const city = user.details?.address?.city ?? 'Unknown';
console.log(city); // Output: 'Unknown'
در این مثال، عملگرهای زنجیره اختیاری (`?.`) با خیال راحت ویژگیهای تودرتو را هدایت میکنند. اگر `user.details` یا `user.details.address` برابر با `undefined` باشد، یا `user.details.address.city` برابر با `null` یا `undefined` باشد، کد 'Unknown' را به `city` اختصاص میدهد. این ساختار به جلوگیری از استثناهای رایج `TypeError` هنگام برخورد با دادههای بالقوه ناقص کمک میکند.
بهترین شیوه ها و ملاحظات
خوانایی و وضوح کد
در حالی که زنجیره ای عملگر ادغام تهی می تواند تا حد زیادی فشردگی کد را بهبود بخشد، حفظ خوانایی مهم است. زنجیرههای بیش از حد طولانی میتوانند درک آن ها دشوار شود. این نکات را در نظر بگیرید:
- زنجیره ها را نسبتاً کوتاه نگه دارید. اگر زنجیره ای با بیش از سه یا چهار عملگر `??` دارید، برای خوانایی بهتر، آن را به چندین خط تقسیم کنید، یا حتی از متغیرهای جداگانه استفاده کنید.
- از نام متغیرهای معنادار استفاده کنید. نام متغیرهای توصیفی درک منطق را آسان تر می کند.
- در صورت لزوم، نظرات اضافه کنید. هدف از زنجیره های پیچیده را توضیح دهید.
ترتیب عملیات
عملگر `??` اولویت نسبتاً پایینی دارد. این بدان معناست که بعد از اکثر عملگرهای دیگر ارزیابی می شود. بنابراین، هنگام ترکیب `??` با سایر عملگرها (به عنوان مثال، عملگرهای حسابی یا عملگرهای منطقی)، مراقب ترتیب عملیات باشید. در صورت نیاز، به ویژه برای عبارات پیچیده، از پرانتز برای تعریف صریح ترتیب ارزیابی استفاده کنید.
const value = (a + b) ?? c; // Evaluates a + b first, then uses ??
مقایسه با عملگر OR (||)
همانطور که قبلاً ذکر شد، عملگر ادغام تهی با عملگر منطقی OR (||) متفاوت است. در حالی که `||` برای بسیاری از مقادیر (از جمله `0`، `''`، `false`، `NaN`، `null` و `undefined`) به `false` ارزیابی می شود، `??` *فقط* برای `null` و `undefined` به `false` ارزیابی می شود. اپراتوری را انتخاب کنید که به بهترین وجه با نیازهای شما مطابقت دارد. به عنوان مثال، هنگام اطمینان از اینکه یک مقدار رشته خالی نیست، و شما با 0 به عنوان یک مقدار معتبر مشکلی ندارید، از `??` استفاده کنید.
چه زمانی از استفاده بیش از حد خودداری کنیم
در حالی که عملگر ادغام تهی ابزاری قدرتمند است، از آن بیش از حد استفاده نکنید. استفاده بیش از حد می تواند منجر به کدی شود که کمتر قابل خواندن است. در اینجا برخی از سناریوها وجود دارد که ممکن است رویکردهای جایگزین بهتر باشند:
- تخصیص های پیش فرض ساده: برای تخصیص های بسیار ساده، یک دستور `if/else` ساده ممکن است واضح تر باشد.
- شرایط منطقی پیچیده: اگر منطق پشت تخصیص مقدار پیش فرض پیچیده است، از یک دستور `if/else` یا یک تابع اختصاصی برای کپسوله کردن منطق استفاده کنید.
مثال های عملی و موارد استفاده جهانی
بیایید برخی از مثال های عملی را بررسی کنیم، با در نظر گرفتن مخاطبان جهانی و زمینه های بین المللی:
مثال 1: بین المللی سازی (i18n) و بومی سازی (l10n)
در برنامه های بین المللی شده، بازیابی متن بومی شده ممکن است شامل بررسی منابع متعدد باشد. عملگر `??` این فرآیند را ساده می کند.
// Assuming an i18n library and locale configuration
const userLocale = getUserLocale(); // e.g., 'fr-CA', 'en-US'
const localizedMessage = translations[userLocale]?.welcomeMessage ?? translations[userLocale.split('-')[0]]?.welcomeMessage ?? translations['en']?.welcomeMessage ?? 'Welcome';
console.log(localizedMessage); // Displays the welcome message using user's preferred language, fallback to language code then 'en'
این کد ابتدا سعی می کند پیام را بر اساس زبان کامل کاربر بازیابی کند (`fr-CA`). اگر این کار انجام نشد (ترجمه در دسترس نیست)، به کد زبان (`fr`) برمی گردد، و اگر *آن* با شکست مواجه شد، به طور پیش فرض به 'en' می رسد.
مثال 2: داده های محصول تجارت الکترونیک
یک پلت فرم تجارت الکترونیک را با جزئیات محصول واکشی شده از یک پایگاه داده تصور کنید. توضیحات محصول، قیمت گذاری و سایر جزئیات ممکن است بسته به منطقه یا در دسترس بودن از دست رفته باشند.
const product = fetchProductData(productId);
const productDescription = product.description ?? product.longDescription ?? 'No description available';
const productPrice = product.salePrice ?? product.regularPrice ?? 0; // Consider using currency formatting
console.log(productDescription); // e.g., 'Premium Leather Wallet' or 'No description available'
console.log(productPrice); // e.g., 75 or 0
این کد به طور موثر احتمال از دست رفتن اطلاعات محصول را مدیریت می کند. عملگر `??` هنگام در دسترس نبودن ویژگی های خاص محصول، مقادیر بازگشتی را ارائه می دهد.
مثال 3: تنظیمات نمایه کاربر و مجوزها
در یک برنامه وب، تنظیمات نمایه کاربر یا سطوح مجوز ممکن است ذخیره شده و به روش های مختلفی دسترسی داشته باشند، احتمالاً از طریق API. عملگر `??` امکان مدیریت آسان داده های از دست رفته یا ناقص را فراهم می کند.
const userData = await fetchUserData(userId);
const userDisplayName = userData.profile?.displayName ?? userData.username ?? 'Guest';
const userTheme = userData.preferences?.theme ?? 'default';
console.log(userDisplayName); // 'JohnDoe' or 'Guest'
console.log(userTheme); // 'dark' or 'default'
در اینجا، نام نمایشی کاربر به طور پیش فرض نام کاربری است اگر نام نمایشی ارائه نشود، و اگر هیچ یک وجود نداشته باشد، کد به طور پیش فرض "مهمان" است. تم کاربر نیز در صورت عدم وجود به طور پیش فرض به پیش فرض می رسد.
مثال 4: پردازش داده های فرم
هنگام مدیریت دادههای فرم، ممکن است اطلاعاتی را از منابع مختلف دریافت کنید. از عملگر `??` میتوان برای تخصیص مقادیر پیشفرض زمانی که یک فیلد فرم خاص پر نشده است، استفاده کرد.
const formData = { /* potentially missing or incomplete data */ };
const userEmail = formData.email ?? ''; // Empty string if email not provided
const userCountry = formData.country ?? 'US'; // Default to US
console.log(userEmail); // user@example.com, or ''
console.log(userCountry); // US, or other default
این کار با ارائه مقادیر پیشفرض منطقی، اعتبارسنجی و پردازش دادههای فرم را ساده میکند.
تکنیک ها و ملاحظات پیشرفته
ترکیب ?? با سایر عملگرها
میتوانید `??` را با سایر عملگرها ترکیب کنید، اما به خاطر داشته باشید که اولویت را در نظر بگیرید و از پرانتز برای وضوح استفاده کنید. به عنوان مثال، ممکن است بخواهید قبل از ارائه یک مقدار پیش فرض، نتیجه دسترسی به یک ویژگی را تأیید کنید:
const age = (user.age >= 0 ? user.age : null) ?? 18; // Ensure age is not negative, and default to 18
توابع مقدار پیش فرض سفارشی
برای منطق مقدار پیش فرض پیچیده تر، می توانید از توابع به عنوان مقادیر پیش فرض استفاده کنید. این امکان محاسبه پویا مقدار پیش فرض را بر اساس سایر متغیرها یا زمینه ها فراهم می کند.
function getDefaultTheme(userRole) {
if (userRole === 'admin') {
return 'dark-admin';
} else {
return 'light';
}
}
const userSettings = { /* ... */ };
const userTheme = userSettings.theme ?? getDefaultTheme(userSettings.role); // Default theme depends on user role
این امر با کپسوله کردن منطق مقدار پیش فرض، کد تمیزتری را ترویج می کند.
استفاده از ?? با زنجیره ای اختیاری (?.)
زنجیره ای اختیاری اغلب در کنار `??` استفاده می شود تا با خیال راحت به ویژگی های اشیاء بالقوه null یا تعریف نشده دسترسی پیدا کنید. این از بروز خطاها جلوگیری می کند و کد را بسیار قوی تر می کند:
const profile = { /* ... */ };
const city = profile?.address?.city ?? 'Unknown'; // Safely accesses nested properties
اگر `profile` یا `profile.address` تعریف نشده باشد، عبارت به جای پرتاب خطا، به آرامی 'Unknown' را برمی گرداند.
مزایای استفاده از زنجیره ای عملگر ادغام تهی
- بهبود خوانایی کد: تخصیص مقدار پیشفرض را ساده میکند و کد را آسانتر برای درک و نگهداری میکند.
- فشردگی: مقدار کد مورد نیاز برای مدیریت مقادیر پیشفرض را کاهش میدهد.
- جلوگیری از خطا: خطر خطاها را هنگام کار با مقادیر بالقوه تعریف نشده یا null، بهویژه هنگام ترکیب با زنجیرههای اختیاری، کاهش میدهد.
- انعطاف پذیری: اجرای آسان منطق مقدار پیش فرض پیچیده از طریق زنجیره ای را امکان پذیر می کند.
- کاهش Boilerplate: از نیاز به دستورات طولانی `if/else` در بسیاری از موارد جلوگیری می کند.
نتیجه
عملگر ادغام تهی (??) جاوااسکریپت ابزاری ارزشمند برای توسعه مدرن جاوااسکریپت است که راهی تمیزتر و مختصرتر برای مدیریت مقادیر پیشفرض ارائه میکند. با تسلط بر تکنیک های زنجیره ای و درک بهترین شیوه ها، می توانید کد جاوااسکریپت قوی تر، خواناتر و قابل نگهداری تری را برای برنامه ها در سراسر جهان بنویسید. به یاد داشته باشید که زمینه برنامه خود را در نظر بگیرید و رویکردی را انتخاب کنید که به بهترین وجه بین فشردگی و وضوح تعادل برقرار کند.
از این اطلاعات برای بهبود مهارت های توسعه جاوااسکریپت خود استفاده کنید و کد تمیزتر و قابل نگهداری تری را برای برنامه های وب خود بنویسید. تمرین کنید، آزمایش کنید و کنجکاو بمانید! برنامه نویسی مبارک!